//    Copyright (C) Kherty.  All rights reserved.
#region

using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Reflection;
using OpenLS.Core.Serialization;
using OpenLS.Drawing;

#endregion

namespace OpenLS.Chart
{
    public class ErrorBars : IOfficeXmlSerializable, IShape, INotifyPropertyChanged
    {
        internal const string xmlName = "errBars";


        private ExtensionElement _extension;
        private ErrorBarDirection direction;
        private NumericDataSource minus;
        private bool noEndCap;
        private NumericDataSource plus;


        private ShapeProperties spPr;
        private ErrorBarType type;


        private double val;
        private ErrorBarValueType valueType;

        public ExtensionElement Extension
        {
            get { return _extension; }
            set
            {
                _extension = value;
                notifyPropertyChanged("Extension");
            }
        }

        public double Value
        {
            get { return val; }
            set
            {
                val = value;
                notifyPropertyChanged("Value");
            }
        }


        public NumericDataSource Minus
        {
            get { return minus; }
            set
            {
                minus = value;
                notifyPropertyChanged("Minus");
            }
        }


        public NumericDataSource Plus
        {
            get { return plus; }
            set
            {
                plus = value;
                notifyPropertyChanged("Plus");
            }
        }


        public bool NoEndCap
        {
            get { return noEndCap; }
            set
            {
                noEndCap = value;
                notifyPropertyChanged("NoEndCap");
            }
        }

        public ErrorBarValueType ValueType
        {
            get { return valueType; }
            set
            {
                valueType = value;
                notifyPropertyChanged("ValueType");
            }
        }


        public ErrorBarType Type
        {
            get { return type; }
            set
            {
                type = value;
                notifyPropertyChanged("Type");
            }
        }

        public ErrorBarDirection Direction
        {
            get { return direction; }
            set
            {
                direction = value;
                notifyPropertyChanged("Direction");
            }
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region IOfficeXmlSerializable Members

        void    IOfficeXmlSerializable.ReadXml(ReadContext context)
        {
            using (var c = context.Read(xmlName))
            {
                Direction = c.ReadOptionalElementEnumAttribute("errDir", ErrorBarDirection.X);
                //\\default OK?
                Type = c.ReadElementEnumAttribute<ErrorBarType>("errBarType");
                ValueType =
                    c.ReadElementEnumAttribute<ErrorBarValueType>("errValType");
                NoEndCap = c.ReadOptionalElementBooleanAttribute("noEndCap", false);
                Plus = NumericDataSource.ReadOptionalNumericDataSource("plus", c);
                Minus = NumericDataSource.ReadOptionalNumericDataSource("minus", c);
                Value = c.ReadOptionalElementDoubleAttribute("val", "val", 0); //\\ default OK?
                ShapeProperties = c.ReadOptionalElement<ShapeProperties>("spPr");
                Extension = c.ReadOptionalElement<ExtensionElement>("extLst");
            }
        }

        void IOfficeXmlSerializable.WriteXml(WriteContext context)
        {
            using (var c = context.Write(xmlName))
            {
                c.WriteOptionalElementEnumAttribute("errDir", Direction, ErrorBarDirection.X);
                //\\default OK?
                c.WriteElementEnumAttribute("errBarType", Type);
                c.WriteElementEnumAttribute("errValType", ValueType);
                c.WriteOptionalElementBooleanAttribute("noEndCap", NoEndCap);
                if (Plus != null)
                {
                    using (var c2 = c.Write("plus"))
                    {
                        c2.WriteElement(Plus);
                    }
                }
                if (Minus != null)
                {
                    using (var c2 = c.Write("minus"))
                    {
                        c2.WriteElement(Minus);
                    }
                }
                c.WriteOptionalElementDoubleAttribute("val", "val", Value, 0); //\\ default OK?
                c.WriteOptionalElement(ShapeProperties);
                c.WriteOptionalElement(Extension);
            }
        }

        #endregion

        #region IShape Members

        public ShapeProperties ShapeProperties
        {
            get { return spPr; }
            set
            {
                spPr = value;
                notifyPropertyChanged("ShapeProperties");
            }
        }

        #endregion

        private void notifyPropertyChanged(string propertyName)
        {
            Contract.Requires(GetType().GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) != null);
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}